/**
 * @file pid.h
 * @brief PID控制算法核心头文件
 *        定义PID结构体、模式枚举及不同场景（底盘/云台）的PID参数配置，包含PID计算和过零处理函数声明
 * @author WeiFan Qiu (qiuweifan0523@faxmail.com)
 * @version 1.0
 * @date 2025-08-08
 * 
 * @copyright Copyright (c) 2025 邱伟凡
 * 
 * @par 修改日志:
 * - 2025-08-08: 初始版本创建，定义基础PID结构体和接口
 * 
 * @bug 待解决问题:
 * - 未实现抗积分饱和的详细策略
 */
#ifndef PID_H
#define PID_H
#include "QWF_Custom_Ctrl.h"
/*********** 宏定义 **************/
#include "QWF_Include.h"

/**
 * @brief PID模式控制位域结构体
 * @details 通过位域标志位控制PID的功能模式（如输出使能、前馈控制等）
 */
typedef __packed struct{
	_Bool out_put;   // PID输出使能（1:启用输出）
	_Bool ffc;       // 前馈控制使能（Feed Forward Control）
	_Bool i_trapezoid; // 积分梯形修正使能（抑制积分超调）
	_Bool i_change;  // 积分变参数使能（根据误差调整积分系数）
	_Bool bit5;      // 保留位5
	_Bool bit6;      // 保留位6
	_Bool bit7;      // 保留位7
	_Bool bit8;      // 保留位8
}pid_mode_t;

/**
 * @brief PID核心控制结构体
 * @details 包含PID算法所需的目标值、测量值、误差、系数及各环节输出等关键参数
 */
typedef __packed struct{
	pid_mode_t mode;     // PID模式控制位域
	float target[2];     // 目标值数组（[0]:当前目标 [1]:上一目标）
	float measure[2];    // 测量值数组（[0]:当前测量 [1]:上一测量）
	float err[2];        // 误差数组（[0]:当前误差 [1]:上一误差）
	float integral;      // 积分项累计值
	float KF, KP, KI, KD, K0; // 前馈系数、比例系数、积分系数、微分系数、修正系数
	float i_change_a, i_change_b; // 积分变参数的a/b系数（用于i_change模式）
	float p_out, i_out, d_out, f_out; // 比例/积分/微分/前馈环节输出
	float output;        // 最终输出值
	float max, min;      // 输出限幅范围（max:上限 min:下限）
	float i_max;         // 积分项限幅值（防止积分饱和）
	float f_max;         // 前馈输出限幅值
	float dead_max, dead_min; // 死区范围（误差在此区间内输出0）
}pid_t;

#if Circuit_Boards!=Head_Circuit_Boards
/**
 * @brief 底盘PID参数结构体（非云台电路板使用）
 * @details 包含底盘各方向（前/后/左/右）的轮速、舵机角度等控制所需的PID实例
 */
typedef struct{
	struct{
		// 特殊控制模式（xyw复合控制）
		pid_t follow;  // 跟随模式PID
		pid_t fly;     // 自由模式PID
		pid_t power;   // 功率限制PID
	}special;
#if Chassis_Wheel_Type==Helf_Helm_Wheel
	struct{// 前轮 f
		struct{//舵向电机 helm
			pid_t w;      // 舵转速PID
			pid_t angle;  // 舵角度PID
		}helm;
		struct{//轮向电机 wheel
			pid_t v;      // 轮速PID
		}wheel;
	}f;
	struct{// 后轮 b
		struct{//舵向电机 helm
			pid_t w;      // 舵转速PID
			pid_t angle;  // 舵角度PID
		}helm;
		struct{//轮向电机 wheel
			pid_t v;      // 轮速PID
		}wheel;
	}b;
	struct{// 左轮 l
		struct{//轮向电机 wheel
			pid_t v;      // 轮速PID
		}wheel;
	}l;
	struct{// 右轮 r
		struct{//轮向电机 wheel
			pid_t v;      // 轮速PID
		}wheel;
	}r;
#elif Chassis_Wheel_Type==Omni_Wheel||Chassis_Wheel_Type==Mecanum_Wheel
	struct{
		pid_t v;
	}lf;
	struct{
		pid_t v;
	}lb;
	struct{
		pid_t v;
	}rf;
	struct{
		pid_t v;
	}rb;	
#elif Chassis_Wheel_Type==Leg_Wheel
	struct{
		pid_t v;
	}l;
	struct{
		pid_t v;
	}r;

#endif
}chassis_pid_t;
extern chassis_pid_t* chassis_pid; // 底盘PID全局指针
#endif

#if Circuit_Boards!=Chassis_Circuit_Boards
/**
 * @brief 云台PID参数结构体（非底盘电路板使用）
 */
typedef __packed struct{
	__packed struct{
		__packed struct{
			pid_t w;      // pitch轴转速PID
			pid_t angle;  // pitch轴角度PID
		}pitch;
		__packed struct{
			pid_t w;      // yaw轴转速PID
			pid_t angle;  // yaw轴角度PID
		}yaw;
	}gimbal;
	__packed struct{
		__packed struct{
			// 拨弹控制
			__packed struct{
				pid_t v;      // 左拨弹速度PID
			}l;
			__packed struct{
				pid_t v;      // 右拨弹速度PID
			}r;
		}fire;
		__packed struct{
			// 旋钮控制
			pid_t w;      // 连发转速PID
			pid_t w_once; // 单发速度环PID
			pid_t angle;  // 单发角度环PID
		}knob;
	}shoot;
}head_pid_t;
extern head_pid_t* head_pid; // 云台PID全局指针
#endif

/**
 * @brief PID核心计算函数
 */
float PID_Calculate(pid_t* pid,float measure /*测量值*/,float calcu /*目标值*/);

/**
 * @brief 过零处理函数（底盘跟随pid用），也可以用find_min_angle替代
 */
float over_zero(float measure /*测量角度值*/,float target /*目标角度值*/,int T,float k);

#endif
